package com.unione.unione_network.tcp_socket

import android.util.Log
import okio.IOException
import java.io.InputStream

/**
 * 特定字符的粘包处理,首尾各一个Byte[],不可以同时为空，如果其中一个为空，那么以不为空的作为分割标记
 * 例：协议制定为  ^+数据+$，首就是^，尾是$
 */
class SpecifiedStickPackageHelper(private val head: ByteArray, private val tail: ByteArray) :
    AbsStickPackageHelper {

    private var bytes: MutableList<Byte> = mutableListOf()

    companion object {
        const val TAG = "SpecifiedStickPackageHelper"
    }

    override fun execute(inputStream: InputStream): ByteArray? {
        bytes.clear()
        var len = -1
        var temp: Byte
        var startIndex = -1
        var result: ByteArray? = null
        var isFindStart = false
        var isFindEnd = false
        val headLen = head.size
        val tailLen = tail.size
        try {
            while (inputStream.read().also { len = it } != -1) {
                temp = len.toByte()
                bytes.add(temp)
                val byteArray = bytes.toByteArray()
                println(String(byteArray, Charsets.UTF_8))
                if (headLen == 0 || tailLen == 0) { //只有头或尾标记
                    if (endWith(byteArray, head) || endWith(byteArray, tail)) {
                        if (startIndex == -1) {
                            startIndex = bytes.size - headLen
                        } else { //找到了
                            result = getRangeBytes(bytes, startIndex, bytes.size)
                            break
                        }
                    }
                } else {
                    if (!isFindStart) {
                        if (endWith(byteArray, head)) {
                            startIndex = bytes.size - headLen
                            isFindStart = true
                        }
                    } else if (!isFindEnd) {
                        if (endWith(byteArray, tail)) {
                            if (startIndex + headLen <= bytes.size - tailLen) {
                                isFindEnd = true
                                result = getRangeBytes(bytes, startIndex, bytes.size)
                                break
                            }
                        }
                    }
                }
            }
            if (len == -1) {
                return null
            }
        } catch (e: IOException) {
            e.printStackTrace()
            return null
        }
        return result


    }

    private fun getRangeBytes(bytes: MutableList<Byte>, start: Int, end: Int): ByteArray {
        return bytes.subList(start, end).map(Byte::toByte).toByteArray()
    }


//    private fun endWith(src: ByteArray, target: ByteArray): Boolean {
//        if (src.size < target.size || target.isEmpty()) {
//            return false
//        }
//        for (i in target.indices) { //逆序比较
//            if (target[target.size - i - 1] != src[src.size - i - 1]) {
//                return false
//            }
//        }
//        return true
//    }

    private fun endWith(src: ByteArray, target: ByteArray): Boolean {
        if (src.size < target.size || target.isEmpty()) {
            return false
        }
        if (String(src, Charsets.UTF_8).endsWith(String(target, Charsets.UTF_8))) {
            return true
        }
        return false
    }
}